/**
 * for in 和for of
 */
const obj = {
  a: 1,
  b: 2,
  c: 3
}
obj[Symbol.iterator] = function () {
  let keys = Object.keys(this)
  let index = 0
  return {
    next: () => {
      if (index < keys.length) {
        let key = keys[index++]
        return {
          value: { [key]: this[key] },
          done: false
        }
      } else {
        return {
          value: undefined,
          done: true
        }
      }
    }
  }
}
const stringTemp = '123456789'
// for (let i in obj) {
//   console.log(i);
// }

for (let i of obj) {
  console.log(i);
}


/*
for in 取的key值
如果是对象，就是对象的key
如果是数组，就是数组的下标
特别情况下, for ... in 循环会以看起来任意的顺序遍历键名
常规属性和排序属性
  --常规属性就是数字属性，按大小升序
  --排序属性就是字符串属性，按创建顺序升序
  --这两个属性分别存在对象的element和properties属性中
*/
/*
for of 取键值对中的值
  --和foreach不同，可以随时退出循环
  --只要有 iterator 接口的数据结构,都可以使用 for of循环
  --凡是部署了 iterator 接口的数据结构也都可以使用数组的扩展运算符(...)和解构赋值等操作
    --数组Array
    --Map
    --Set
    --String
    --arguments对象
    --Nodelist对象, 就是获取的dom列表集合
  --想用for of循环对象
    --用object.keys()
    --给对象设置Symbol.iterator
*/


/*
iterator接口是啥
  --obj[Symbol.iterator]是一个函数，该函数返回一个iterator
  --内部有next函数，
  --调用next可以进行调用，返回格式{value:xx，done:true/false}
  --done为true就是结束

*/


/*
为什么对象没有部署iterator接口
  --对象的哪个属性先遍历，哪个属性后遍历是不确定的，需要开发者手动指定。
    然而遍历遍历器是一种线性处理，对于非线性的数据结构，
    部署遍历器接口，就等于要部署一种线性转换。
  --对对象部署Iterator接口并不是很必要，因为Map弥补了它的缺陷，又正好有Iteraotr接口
*/

/*
怎么给对象部署iterator接口
  --
*/